home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 February / EnigmA AMIGA RUN 15 (1997)(G.R. Edizioni)(IT)[!][issue 1997-02][PLANET CD V].iso / enigma / earcd / sviluppo / svilupp2 / gmsppr10.lha / Sprites.c < prev    next >
C/C++ Source or Header  |  1996-09-30  |  32KB  |  1,280 lines

  1. #ifndef INTUITION_IMAGECLASS_H
  2. #include <intuition/imageclass.h>
  3. #endif
  4.  
  5. #include <proto/alib.h>
  6. #include <proto/exec.h>
  7. #include <proto/dos.h>
  8. #include <proto/iffparse.h>
  9. #include <proto/graphics.h>
  10. #include <proto/intuition.h>
  11.  
  12. #include "Global.h"
  13. #include "SPRT.h"
  14.  
  15. #define SPRTF_FREE        (1<<10)
  16.  
  17. /************************************************************************/
  18.  
  19. struct Global
  20. {
  21.   struct Library *LibBase;
  22.   BPTR File;
  23.   struct Screen *Screen;
  24.  
  25.   LONG Error;
  26.  
  27.   struct Window *Window;
  28.   Object *FrameImage;
  29.   Object *RectImage;
  30.  
  31.   UWORD MaxWidth;
  32.   UWORD SpriteCount;
  33.   UWORD SpritesDone;
  34. };
  35.  
  36. #define IFFParseBase    (Global->LibBase)
  37.  
  38. /************************************************************************/
  39.  
  40. struct SetInfo
  41. {
  42.   ULONG Number;            /* the ordinal number of the sprite set */
  43.   ULONG ColorCount;        /* how many colors did we want? */
  44.   ULONG DistinctColors;        /* how many colors did we get? */
  45. };
  46.  
  47. struct OriginalSprite
  48. {
  49.   struct BitMap Bitmap;
  50.   WORD Width, Height;
  51. };
  52.  
  53. struct BMHD
  54. {
  55.   UWORD Width, Height;
  56.   WORD Left, Top;
  57.   UBYTE Depth;
  58.   UBYTE Masking;
  59.   UBYTE Compression;
  60.   UBYTE Pad;
  61.   UWORD TransparentColor;
  62.   UBYTE XAspect, YAspect;
  63.   WORD PageWidth, PageHeight;
  64. };
  65.  
  66. /************************************************************************/
  67. /*                                    */
  68. /* Create a 32 bit word from a byte                    */
  69. /*                                    */
  70. /************************************************************************/
  71.  
  72. static INLINE ULONG Extend32(UBYTE Byte)
  73.  
  74. {
  75.   union
  76.     {
  77.       ULONG Long;
  78.       UBYTE Byte[4];
  79.     } Conv;
  80.  
  81.   Conv.Byte[0]=Conv.Byte[1]=Conv.Byte[2]=Conv.Byte[3]=Byte;
  82.   return Conv.Long;
  83. }
  84.  
  85. /************************************************************************/
  86. /*                                    */
  87. /* Close the progress window                        */
  88. /*                                    */
  89. /************************************************************************/
  90.  
  91. static INLINE void CloseProgressWindow(struct Global *Global)
  92.  
  93. {
  94.   if (Global->RectImage)
  95.     {
  96.       if (Global->FrameImage)
  97.     {
  98.       if (Global->Window)
  99.         {
  100.           CloseWindow(Global->Window);
  101.           Global->Window=NULL;
  102.         }
  103.       DisposeObject(Global->FrameImage);
  104.       Global->FrameImage=NULL;
  105.     }
  106.       DisposeObject(Global->RectImage);
  107.       Global->RectImage=NULL;
  108.     }
  109. }
  110.  
  111. /************************************************************************/
  112. /*                                    */
  113. /* Create thw progress window                        */
  114. /*                                    */
  115. /************************************************************************/
  116.  
  117. static INLINE void CreateProgressWindow(struct Global *Global, const char *Gamename)
  118.  
  119. {
  120.   struct DrawInfo *DrawInfo;
  121.  
  122.   Global->FrameImage=NULL;
  123.   Global->RectImage=NULL;
  124.   Global->Window=NULL;
  125.  
  126.   if ((DrawInfo=GetScreenDrawInfo(Global->Screen)))
  127.     {
  128.       static struct TagItem ConstantImageTags[]=
  129.     {
  130.       {IA_Recessed, TRUE},
  131.       {IA_EdgesOnly, TRUE},
  132.       {TAG_DONE}
  133.     };
  134.  
  135.       struct TagItem Tags[7];
  136.       struct TextFont *Font;
  137.  
  138.       Font=DrawInfo->dri_Font;
  139.  
  140.       Tags[0].ti_Tag=IA_Width;
  141.       Tags[0].ti_Data=16*Font->tf_YSize;
  142.       Tags[1].ti_Tag=IA_Height;
  143.       Tags[1].ti_Data=3*Font->tf_YSize/2;
  144.       Tags[2].ti_Tag=IA_Top;
  145.       Tags[2].ti_Data=Font->tf_YSize/2;
  146.       Tags[3].ti_Tag=IA_Left;
  147.       Tags[3].ti_Data=Font->tf_XSize;
  148.       Tags[4].ti_Tag=IA_FGPen;
  149.       Tags[4].ti_Data=DrawInfo->dri_Pens[FILLPEN];
  150.       Tags[5].ti_Tag=IA_BGPen;
  151.       Tags[5].ti_Data=DrawInfo->dri_Pens[BACKGROUNDPEN];
  152.       Tags[6].ti_Tag=TAG_MORE;
  153.       Tags[6].ti_Data=(ULONG)ConstantImageTags;
  154.       Global->MaxWidth=Tags[0].ti_Data;
  155.       if ((Global->RectImage=NewObjectA(NULL,"fillrectclass",Tags)))
  156.     {
  157.       if ((Global->FrameImage=NewObjectA(NULL,"frameiclass",Tags)))
  158.         {
  159.           static const struct TagItem ConstantWindowTags[]=
  160.         {
  161.           {WA_Flags, (WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_NOCAREREFRESH | WFLG_RMBTRAP | WFLG_SMART_REFRESH)},
  162.           {WA_BusyPointer, TRUE},
  163.           {TAG_DONE}
  164.         };
  165.  
  166.           {
  167.         struct IBox RectIBox;
  168.         struct IBox FrameIBox;
  169.         struct impFrameBox impFrameBox;
  170.  
  171.         RectIBox.Left=Tags[3].ti_Data;
  172.         RectIBox.Top=Tags[2].ti_Data;
  173.         RectIBox.Width=Tags[0].ti_Data;
  174.         RectIBox.Height=Tags[1].ti_Data;
  175.         impFrameBox.MethodID=IM_FRAMEBOX;
  176.         impFrameBox.imp_FrameBox=&FrameIBox;
  177.         impFrameBox.imp_ContentsBox=&RectIBox;
  178.         impFrameBox.imp_DrInfo=DrawInfo;
  179.         impFrameBox.imp_FrameFlags=0;
  180.         DoMethodA(Global->FrameImage,&impFrameBox);
  181.  
  182.         Tags[3].ti_Data=FrameIBox.Left;
  183.         Tags[2].ti_Data=FrameIBox.Top;
  184.         Tags[0].ti_Data=FrameIBox.Width;
  185.         Tags[1].ti_Data=FrameIBox.Height;
  186.         Tags[4].ti_Tag=TAG_DONE;
  187.           }
  188.           SetAttrsA(Global->FrameImage,Tags);
  189.  
  190.           Tags[0].ti_Tag=WA_InnerWidth;
  191.           Tags[0].ti_Data+=2*Tags[3].ti_Data;
  192.           Tags[1].ti_Tag=WA_InnerHeight;
  193.           Tags[1].ti_Data+=2*Tags[2].ti_Data;
  194.           Tags[2].ti_Tag=WA_CustomScreen;
  195.           Tags[2].ti_Data=(ULONG)Global->Screen;
  196.           Tags[3].ti_Tag=WA_Title;
  197.           Tags[3].ti_Data=(ULONG)Gamename;
  198.           Tags[4].ti_Tag=TAG_MORE;
  199.           Tags[4].ti_Data=(ULONG)ConstantWindowTags;
  200.           if ((Global->Window=OpenWindowTagList(NULL,Tags)))
  201.         {
  202.           DrawImage(Global->Window->RPort,(struct Image *)Global->FrameImage,
  203.                 Global->Window->BorderLeft,Global->Window->BorderTop);
  204.         }
  205.         }
  206.     }
  207.       FreeScreenDrawInfo(Global->Screen,DrawInfo);
  208.     }
  209. }
  210.  
  211. /************************************************************************/
  212. /*                                    */
  213. /* Increase the sprite count for the progress window            */
  214. /* Update the progress window                        */
  215. /*                                    */
  216. /************************************************************************/
  217.  
  218. static void UpdateProgressWindow(struct Global *Global)
  219.  
  220. {
  221.   struct TagItem RectTags[2];
  222.  
  223.   Global->SpritesDone++;
  224.   RectTags[0].ti_Tag=IA_Width;
  225.   RectTags[0].ti_Data=Global->MaxWidth*Global->SpritesDone/Global->SpriteCount;
  226.   RectTags[1].ti_Tag=TAG_DONE;
  227.   SetAttrsA(Global->RectImage,RectTags);
  228.   if (AttemptLockLayerRom(Global->Window->RPort->Layer))
  229.     {
  230.       DrawImage(Global->Window->RPort,(struct Image *)Global->RectImage,
  231.         Global->Window->BorderLeft,Global->Window->BorderTop);
  232.       UnlockLayerRom(Global->Window->RPort->Layer);
  233.     }
  234. }
  235.  
  236. /************************************************************************/
  237. /*                                    */
  238. /*                                    */
  239. /************************************************************************/
  240.  
  241. static void ExpandCMAP(UBYTE *ColorByte, struct GS_ColorDef *ColorDef)
  242.  
  243. {
  244.   struct GS_Color *Color;
  245.   ULONG ColorCount;
  246.  
  247.   Color=ColorDef->Colors;
  248.   ColorCount=ColorDef->ColorCount;
  249.   while (ColorCount)
  250.     {
  251.       Color->Red=Extend32(*(ColorByte++));
  252.       Color->Green=Extend32(*(ColorByte++));
  253.       Color->Blue=Extend32(*(ColorByte++));
  254.       Color++;
  255.       ColorCount--;
  256.     }
  257. }
  258.  
  259. /************************************************************************/
  260. /*                                    */
  261. /* Look at all sprite sets and return some information about them.    */
  262. /* We must have locked the PaletteExtra, to avoid race-conditions.    */
  263. /*                                    */
  264. /************************************************************************/
  265.  
  266. static INLINE struct SetInfo *GetSetInfo(struct Global *Global, ULONG *SetCount)
  267.  
  268. {
  269.   struct SetInfo *SetInfo;
  270.  
  271.   SetInfo=NULL;
  272.   if (Seek(Global->File,0,OFFSET_BEGINNING)!=-1)
  273.     {
  274.       struct IFFHandle *IFFHandle;
  275.  
  276.       if ((IFFHandle=AllocIFF()))
  277.     {
  278.       LONG ErrorCode;
  279.  
  280.       IFFHandle->iff_Stream=Global->File;
  281.       InitIFFasDOS(IFFHandle);
  282.       if (!(ErrorCode=OpenIFF(IFFHandle,IFFF_READ)))
  283.         {
  284.           if (!(ErrorCode=StopOnExit(IFFHandle,MAKE_ID('S','P','R','T'),MAKE_ID('F','O','R','M'))) &&
  285.           !(ErrorCode=PropChunk(IFFHandle,MAKE_ID('S','P','R','T'),MAKE_ID('C','M','A','P'))))
  286.         {
  287.           ULONG Count;
  288.           ULONG ArraySize;
  289.  
  290.           Count=0;
  291.           ArraySize=0;
  292.           do
  293.             {
  294.               ErrorCode=ParseIFF(IFFHandle,IFFPARSE_SCAN);
  295.               if (ErrorCode==IFFERR_EOC)
  296.             {
  297.               if (ArraySize==Count)
  298.                 {
  299.                   struct SetInfo *NewSetInfo;
  300.  
  301.                   ArraySize+=16;
  302.                   if (!(NewSetInfo=GS_MemoryRealloc(SetInfo,ArraySize*sizeof(*NewSetInfo))))
  303.                 {
  304.                   GS_MemoryFree(SetInfo);
  305.                   ErrorCode=ERROR_NO_FREE_STORE;
  306.                 }
  307.                   SetInfo=NewSetInfo;
  308.                 }
  309.               if (SetInfo)
  310.                 {
  311.                   struct StoredProperty *CMAP;
  312.  
  313.                   SetInfo[Count].Number=Count;
  314.                   SetInfo[Count].ColorCount=0;
  315.                   SetInfo[Count].DistinctColors=0;
  316.                   if ((CMAP=FindProp(IFFHandle,MAKE_ID('S','P','R','T'),MAKE_ID('C','M','A','P'))))
  317.                 {
  318.                   struct GS_ColorDef *Colors;
  319.                   ULONG ColorCount;
  320.  
  321.                   if ((ColorCount=CMAP->sp_Size/3))
  322.                     {
  323.                       if ((Colors=GS_MemoryAlloc(sizeof(*Colors)+(ColorCount)*sizeof(struct GS_Color))))
  324.                     {
  325.                       Colors->ColorCount=ColorCount;
  326.                       SetInfo[Count].ColorCount=ColorCount;
  327.                       ExpandCMAP(CMAP->sp_Data,Colors);
  328.                       if (GS_AllocateColors(Global->Screen,Colors,0))
  329.                         {
  330.                           SetInfo[Count].DistinctColors=Colors->DistinctColors;
  331.                           GS_FreeColors(Global->Screen,Colors);
  332.                         }
  333.                       else if (ErrorCode=IoErr())
  334.                         {
  335.                           GS_MemoryFree(SetInfo);
  336.                           SetInfo=NULL;
  337.                         }
  338.                       GS_MemoryFree(Colors);
  339.                     }
  340.                       else
  341.                     {
  342.                       GS_MemoryFree(SetInfo);
  343.                       SetInfo=NULL;
  344.                       ErrorCode=ERROR_NO_FREE_STORE;
  345.                     }
  346.                     }
  347.                 }
  348.                   Count++;
  349.                 }
  350.             }
  351.               else if (ErrorCode!=IFFERR_EOF)
  352.             {
  353.               GS_MemoryFree(SetInfo);
  354.               SetInfo=NULL;
  355.             }
  356.             }
  357.           while (SetInfo && ErrorCode!=IFFERR_EOF);
  358.           if (SetInfo)
  359.             {
  360.               *SetCount=Count;
  361.             }
  362.           else if (ErrorCode==IFFERR_EOF && !Count)
  363.             {
  364.               ErrorCode=ERROR_OBJECT_WRONG_TYPE;
  365.             }
  366.         }
  367.           CloseIFF(IFFHandle);
  368.         }
  369.       if (!SetInfo)
  370.         {
  371.           Global->Error=ErrorCode;
  372.         }
  373.       FreeIFF(IFFHandle);
  374.     }
  375.       else
  376.     {
  377.       Global->Error=ERROR_NO_FREE_STORE;
  378.     }
  379.     }
  380.   else
  381.     {
  382.       Global->Error=IoErr();
  383.     }
  384.   return SetInfo;
  385. }
  386.  
  387. /************************************************************************/
  388. /*                                    */
  389. /* Select the sprite set to use                        */
  390. /*                                    */
  391. /************************************************************************/
  392.  
  393. static INLINE struct SetInfo *SelectSet(struct Global *Global, struct SetInfo *SetInfo, ULONG SetCount)
  394.  
  395. {
  396.   struct SetInfo *BestSet;
  397.   ULONG BestIndex;
  398.  
  399.   BestIndex=0;
  400.   BestSet=SetInfo;
  401.   while (SetCount)
  402.     {
  403.       ULONG Index;
  404.  
  405.       Index=65536*SetInfo->DistinctColors*SetInfo->DistinctColors/SetInfo->ColorCount;
  406.       if (Index>BestIndex)
  407.     {
  408.       BestIndex=Index;
  409.       BestSet=SetInfo;
  410.     }
  411.       SetInfo++;
  412.       SetCount--;
  413.     }
  414.   return BestSet;
  415. }
  416.  
  417. /************************************************************************/
  418. /*                                    */
  419. /* Find the selected FORM SPRT                        */
  420. /*                                    */
  421. /************************************************************************/
  422.  
  423. static INLINE LONG FindSet(struct Global *Global, struct IFFHandle *IFFHandle, struct SetInfo *SetInfo)
  424.  
  425. {
  426.   LONG Error;
  427.   ULONG Count;
  428.  
  429.   Error=StopChunk(IFFHandle,MAKE_ID('S','P','R','T'),MAKE_ID('F','O','R','M'));
  430.   Count=FALSE;
  431.   while (!Error)
  432.     {
  433.       if (!(Error=ParseIFF(IFFHandle,IFFPARSE_SCAN)))
  434.     {
  435.       if (Count==SetInfo->Number)
  436.         {
  437.           break;
  438.         }
  439.       Count++;
  440.     }
  441.     }
  442.   if (Error)
  443.     {
  444.       Global->Error=Error;
  445.     }
  446.   return Error;
  447. }
  448.  
  449. /************************************************************************/
  450. /*                                    */
  451. /* Create the sprite array                        */
  452. /*                                    */
  453. /************************************************************************/
  454.  
  455. static INLINE struct GS_Sprites *InitSpriteArray(struct Global *Global, struct IFFHandle *IFFHandle, struct SetInfo *SetInfo)
  456.  
  457. {
  458.   struct StoredProperty *SPRTProperty;
  459.   struct GS_Sprites *Sprites;
  460.   LONG ErrorCode;
  461.  
  462.   Sprites=NULL;
  463.   ErrorCode=IFFERR_MANGLED;
  464.   if ((SPRTProperty=FindProp(IFFHandle,MAKE_ID('S','P','R','T'),MAKE_ID('S','P','R','T'))))
  465.     {
  466.       ULONG SpriteCount;
  467.  
  468.       if ((SpriteCount=SPRTProperty->sp_Size/sizeof(struct SPRT)))
  469.     {
  470.       struct StoredProperty *CMAPProperty;
  471.  
  472.       Global->SpriteCount=SpriteCount;
  473.       if ((CMAPProperty=FindProp(IFFHandle,MAKE_ID('S','P','R','T'),MAKE_ID('C','M','A','P'))))
  474.         {
  475.           ULONG ColorCount;
  476.  
  477.           ColorCount=CMAPProperty->sp_Size/3;
  478.           if (ColorCount==SetInfo->ColorCount)
  479.         {
  480.           if ((Sprites=GS_MemoryAlloc(sizeof(struct GS_Sprites)+
  481.                           sizeof(struct GS_Color)*ColorCount+
  482.                           sizeof(struct GS_Sprite)*SpriteCount)))
  483.             {
  484.               Sprites->SpriteCount=SpriteCount;
  485.               Sprites->Colors.ColorCount=ColorCount;
  486.               Sprites->Sprites=(struct Sprite *)&Sprites->Colors.Colors[ColorCount];
  487.               {
  488.             struct SPRT *SPRT;
  489.             struct GS_Sprite *Sprite;
  490.             
  491.             SPRT=SPRTProperty->sp_Data;
  492.             Sprite=Sprites->Sprites;
  493.             while (SpriteCount)
  494.               {
  495.                 Sprite->Image=NULL;
  496.                 Sprite->Mask=NULL;
  497.                 Sprite->Width=SPRT->Original;
  498.                 Sprite->Height=0;
  499.                 Sprite->Flags=SPRT->Flags;
  500.                 Sprite++;
  501.                 SPRT++;
  502.                 SpriteCount--;
  503.               }
  504.               }
  505.               ExpandCMAP(CMAPProperty->sp_Data,&Sprites->Colors);
  506.               if ((GS_AllocateColors(Global->Screen,&Sprites->Colors,0)))
  507.             {
  508.               ErrorCode=0;
  509.               if (Sprites->Colors.DistinctColors!=SetInfo->DistinctColors)
  510.                 {
  511.                   ErrorCode=0;
  512.                   GS_FreeSprites(Sprites,Global->Screen);
  513.                   Sprites=NULL;
  514.                 }
  515.             }
  516.               else
  517.             {
  518.               ErrorCode=IoErr();
  519.               GS_FreeSprites(Sprites,Global->Screen);
  520.               Sprites=NULL;
  521.             }
  522.             }
  523.           else
  524.             {
  525.               ErrorCode=ERROR_NO_FREE_STORE;
  526.             }
  527.         }
  528.         }
  529.     }
  530.     }
  531.   if (ErrorCode)
  532.     {
  533.       Global->Error=ErrorCode;
  534.     }
  535.   return Sprites;
  536. }
  537.  
  538. /************************************************************************/
  539. /*                                    */
  540. /* Take an ILBM CMAP and return a table of pens                */
  541. /*                                    */
  542. /************************************************************************/
  543.  
  544. static INLINE LONG *GetPens(struct Global *Global, const struct StoredProperty *CMAP, const struct GS_Sprites *Sprites)
  545.  
  546. {
  547.   ULONG ColorCount;
  548.   LONG *Pens;
  549.  
  550.   ColorCount=CMAP->sp_Size/3;
  551.   if ((Pens=GS_MemoryAlloc(ColorCount*sizeof(*Pens))))
  552.     {
  553.       UBYTE *ColorByte;
  554.       LONG *Pen;
  555.  
  556.       ColorByte=CMAP->sp_Data;
  557.       Pen=Pens;
  558.       while (ColorCount)
  559.     {
  560.       ULONG Red, Green, Blue;
  561.       ULONG i;
  562.  
  563.       Red=Extend32(*(ColorByte++));
  564.       Green=Extend32(*(ColorByte++));
  565.       Blue=Extend32(*(ColorByte++));
  566.       for (i=0;
  567.            i<Sprites->Colors.ColorCount &&
  568.            (Sprites->Colors.Colors[i].Red!=Red ||
  569.         Sprites->Colors.Colors[i].Green!=Green ||
  570.         Sprites->Colors.Colors[i].Blue!=Blue);
  571.            i++)
  572.         ;
  573.       if (i==Sprites->Colors.ColorCount)
  574.         {
  575.           Global->Error=IFFERR_MANGLED;
  576.           GS_MemoryFree(Pens);
  577.           return NULL;
  578.         }
  579.       else
  580.         {
  581.           *(Pen++)=Sprites->Colors.Colors[i].Pen;
  582.         }
  583.       ColorCount--;
  584.     }
  585.     }
  586.   else
  587.     {
  588.       Global->Error=ERROR_NO_FREE_STORE;
  589.     }
  590.   return Pens;
  591. }
  592.  
  593. /************************************************************************/
  594. /*                                    */
  595. /* Read an ILBM and remap it                        */
  596. /*                                    */
  597. /************************************************************************/
  598.  
  599. static INLINE LONG ReadILBM(struct Global *Global, struct IFFHandle *IFFHandle, struct GS_Sprite *Sprite, struct GS_Sprites *Sprites)
  600.  
  601. {
  602.   struct StoredProperty *BMHDProperty;
  603.  
  604.   if ((BMHDProperty=FindProp(IFFHandle,MAKE_ID('I','L','B','M'),MAKE_ID('B','M','H','D'))))
  605.     {
  606.       if ((BMHDProperty->sp_Size==sizeof(struct BMHD)))
  607.     {
  608.       struct BMHD *BMHD;
  609.       const struct StoredProperty *CMAP;
  610.  
  611.       BMHD=BMHDProperty->sp_Data;
  612.       if ((CMAP=FindProp(IFFHandle,MAKE_ID('I','L','B','M'),MAKE_ID('C','M','A','P'))) || BMHD->Depth==1)
  613.         {
  614.           struct BitMap *Image;
  615.           WORD Bytes;
  616.  
  617.           /* read the image into a native Amiga bitmap */
  618.           Bytes=((BMHD->Width+15)/16)*2;
  619.           if ((Image=AllocBitMap(Bytes*8,BMHD->Height,BMHD->Depth,0,NULL)))
  620.         {
  621.           WORD Row;
  622.  
  623.           for (Row=0; Global->Error==0 && Row<BMHD->Height; Row++)
  624.             {
  625.               WORD Plane;
  626.  
  627.               for (Plane=0; Image && Plane<BMHD->Depth; Plane++)
  628.             {
  629.               Global->Error=MyReadChunkBytes(IFFParseBase,
  630.                              IFFHandle,
  631.                              ((UBYTE *)Image->Planes[Plane])+
  632.                              Row*Image->BytesPerRow,
  633.                              Bytes);
  634.             }
  635.             }
  636.           if (Global->Error==0)
  637.             {
  638.               Sprite->Width=BMHD->Width;
  639.               Sprite->Height=BMHD->Height;
  640.               if (CMAP)
  641.             {
  642.               LONG *Pens;
  643.  
  644.               assert(!(Sprite->Flags & SPRTF_NOIMAGE));
  645.               if ((Pens=GetPens(Global,CMAP,Sprites)))
  646.                 {
  647.                   struct DrawInfo *DrawInfo;
  648.  
  649.                   if ((DrawInfo=GetScreenDrawInfo(Global->Screen)))
  650.                 {
  651.                   ULONG Depth;
  652.                   struct BitMap PlaneBitmap;
  653.  
  654.                   Depth=DrawInfo->dri_Depth;
  655.                   InitBitMap(&PlaneBitmap,1,Image->BytesPerRow*8,Image->Rows);
  656.  
  657.                   /* copy & remap the image */
  658.                   if ((Sprite->Image=AllocBitMap(Sprite->Width, Sprite->Height, Depth,
  659.                                  BMF_INTERLEAVED | BMF_CLEAR,
  660.                                  Global->Screen->RastPort.BitMap)))
  661.                     {
  662.                       struct BitMap *Temp;
  663.  
  664.                       PlaneBitmap.Depth=Depth;
  665.                       if ((Temp=AllocBitMap(Sprite->Width, Sprite->Height, Depth,
  666.                                 BMF_INTERLEAVED, Global->Screen->RastPort.BitMap)))
  667.                     {
  668.                       ULONG Color;
  669.                       struct RastPort RastPort;
  670.  
  671.                       InitRastPort(&RastPort);
  672.                       RastPort.BitMap=Temp;
  673.                       for (Color=(Sprite->Flags & SPRTF_NOMASK) ? 0 : 1;
  674.                            Color<CMAP->sp_Size/3;
  675.                            Color++)
  676.                         {
  677.                           WORD Plane;
  678.  
  679.                           SetRast(&RastPort,Pens[Color]);
  680.                           for (Plane=Image->Depth; Plane--;)
  681.                         {
  682.                           WORD i;
  683.  
  684.                           for (i=Depth; i--;)
  685.                             {
  686.                               PlaneBitmap.Planes[i]=Image->Planes[Plane];
  687.                             }
  688.                           if (Color & (1<<Plane))
  689.                             {
  690.                               /* AND */
  691.                               BltBitMap(&PlaneBitmap,0,0,Temp,0,0,
  692.                                 Sprite->Width,Sprite->Height,0x80,0xff,NULL);
  693.                             }
  694.                           else
  695.                             {
  696.                               /* MASK */
  697.                               BltBitMap(&PlaneBitmap,0,0,Temp,0,0,
  698.                                 Sprite->Width,Sprite->Height,0x20,0xff,NULL);
  699.                             }
  700.                         }
  701.                           /* OR */
  702.                           BltBitMap(Temp,0,0,Sprite->Image,0,0,
  703.                             Sprite->Width,Sprite->Height,0xe0,0xff,NULL);
  704.                         }
  705.                       WaitBlit();
  706.                       FreeBitMap(Temp);
  707.                     }
  708.                       else
  709.                     {
  710.                       Global->Error=ERROR_NO_FREE_STORE;
  711.                     }
  712.                       if (Global->Error!=0)
  713.                     {
  714.                       FreeBitMap(Sprite->Image);
  715.                       Sprite->Image=NULL;
  716.                     }
  717.                     }
  718.                   else
  719.                     {
  720.                       Global->Error=ERROR_NO_FREE_STORE;
  721.                     }
  722.  
  723.                   /* create the mask */
  724.                   if (Global->Error==0 && !(Sprite->Flags & SPRTF_NOMASK))
  725.                     {
  726.                       WORD MaskDepth;
  727.  
  728.                       if (GetBitMapAttr(Sprite->Image,BMA_FLAGS) & BMF_STANDARD)
  729.                     {
  730.                       WORD Plane;
  731.  
  732.                       if ((Sprite->Mask=AllocBitMap(Sprite->Width, Sprite->Height, 1, 0, NULL)))
  733.                         {
  734.                           for (Plane=1; Plane<Depth; Plane++)
  735.                         {
  736.                           Sprite->Mask->Planes[Plane]=Sprite->Mask->Planes[0];
  737.                         }
  738.                           Sprite->Mask->Depth=Depth;
  739.                           MaskDepth=1;
  740.                           PlaneBitmap.Depth=1;
  741.                         }
  742.                     }
  743.                       else
  744.                     {
  745.                       if ((Sprite->Mask=AllocBitMap(Sprite->Width, Sprite->Height, Depth,
  746.                                     BMF_INTERLEAVED,
  747.                                     Global->Screen->RastPort.BitMap)))
  748.                         {
  749.                           MaskDepth=Depth;
  750.                           PlaneBitmap.Depth=Depth;
  751.                         }
  752.                     }
  753.                       if (Sprite->Mask!=NULL)
  754.                     {
  755.                       WORD Plane;
  756.  
  757.                       for (Plane=0; Plane<Image->Depth; Plane++)
  758.                         {
  759.                           WORD i;
  760.  
  761.                           for (i=0; i<MaskDepth; i++)
  762.                         {
  763.                           PlaneBitmap.Planes[i]=Image->Planes[Plane];
  764.                         }
  765.                           if (Plane)
  766.                         {
  767.                           BltBitMap(&PlaneBitmap,0,0,Sprite->Mask,0,0,
  768.                                 Sprite->Width,Sprite->Height,0xe0,0xff,NULL);
  769.                         }
  770.                           else
  771.                         {
  772.                           BltBitMap(&PlaneBitmap,0,0,Sprite->Mask,0,0,
  773.                                 Sprite->Width,Sprite->Height,0xc0,0xff,NULL);
  774.                         }
  775.                         }
  776.                     }
  777.                       else
  778.                     {
  779.                       Global->Error=ERROR_NO_FREE_STORE;
  780.                     }
  781.                     }
  782.                   FreeScreenDrawInfo(Global->Screen,DrawInfo);
  783.                 }
  784.                   else
  785.                 {
  786.                   Global->Error=ERROR_NO_FREE_STORE;
  787.                 }
  788.                   GS_MemoryFree(Pens);
  789.                 }
  790.             }
  791.               else
  792.             {
  793.               assert(Sprite->Flags & SPRTF_NOIMAGE);
  794.               Sprite->Image=Image;
  795.               Image=NULL;
  796.             }
  797.             }
  798.           WaitBlit();
  799.           FreeBitMap(Image);
  800.         }
  801.           else
  802.         {
  803.           Global->Error=ERROR_NO_FREE_STORE;
  804.         }
  805.         }
  806.       else
  807.         {
  808.           Global->Error=IFFERR_MANGLED;
  809.         }
  810.     }
  811.       else
  812.     {
  813.       Global->Error=IFFERR_MANGLED;
  814.     }
  815.     }
  816.   else
  817.     {
  818.       Global->Error=IFFERR_MANGLED;
  819.     }
  820.   return Global->Error;
  821. }
  822.  
  823. /************************************************************************/
  824. /*                                    */
  825. /* Read the original sprites from the selected set.            */
  826. /* This returns the full sprite array, but only the original sprites    */
  827. /* are already initialized.                        */
  828. /* The reflected sprites will have Width=Source                */
  829. /*                                    */
  830. /************************************************************************/
  831.  
  832. static INLINE struct GS_Sprites *ReadOriginalSprites(struct Global *Global, struct SetInfo *SetInfo)
  833.  
  834. {
  835.   struct GS_Sprites *Sprites;
  836.  
  837.   Sprites=NULL;
  838.   if (Seek(Global->File,0,OFFSET_BEGINNING)!=-1)
  839.     {
  840.       struct IFFHandle *IFFHandle;
  841.  
  842.       if ((IFFHandle=AllocIFF()))
  843.     {
  844.       LONG Error;
  845.  
  846.       IFFHandle->iff_Stream=Global->File;
  847.       InitIFFasDOS(IFFHandle);
  848.       if (!(Error=OpenIFF(IFFHandle,IFFF_READ)))
  849.         {
  850.           if (!(Error=FindSet(Global,IFFHandle,SetInfo)))
  851.         {
  852.           static struct {ULONG Type; ULONG ID;} PropArray[]=
  853.             {
  854.               {MAKE_ID('S','P','R','T'),MAKE_ID('C','M','A','P')},
  855.               {MAKE_ID('S','P','R','T'),MAKE_ID('S','P','R','T')},
  856.               {MAKE_ID('I','L','B','M'),MAKE_ID('B','M','H','D')},
  857.               {MAKE_ID('I','L','B','M'),MAKE_ID('C','M','A','P')}
  858.             };
  859.  
  860.           if (!(Error=PropChunks(IFFHandle,(ULONG *)PropArray,ARRAYSIZE(PropArray))) &&
  861.               !(Error=StopChunk(IFFHandle,MAKE_ID('I','L','B','M'),MAKE_ID('B','O','D','Y'))) &&
  862.               !(Error=StopOnExit(IFFHandle,MAKE_ID('S','P','R','T'),MAKE_ID('F','O','R','M'))))
  863.             {
  864.               ULONG OriginalCount;
  865.  
  866.               OriginalCount=0;
  867.               do
  868.             {
  869.               Error=ParseIFF(IFFHandle,IFFPARSE_SCAN);
  870.               if (Error==0)
  871.                 {
  872.                   struct ContextNode *ContextNode;
  873.  
  874.                   ContextNode=CurrentChunk(IFFHandle);
  875.                   if (ContextNode->cn_Type==MAKE_ID('I','L','B','M') && ContextNode->cn_ID==MAKE_ID('B','O','D','Y'))
  876.                 {
  877.                   if (OriginalCount==0)
  878.                     {
  879.                       Sprites=InitSpriteArray(Global,IFFHandle,SetInfo);
  880.                     }
  881.                   if (Sprites)
  882.                     {
  883.                       ULONG i;
  884.  
  885.                       for (i=0; i<Sprites->SpriteCount; i++)
  886.                     {
  887.                       if (!Sprites->Sprites[i].Image &&
  888.                           (Sprites->Sprites[i].Flags & SPRTF_ORIGINAL) &&
  889.                           (Sprites->Sprites[i].Width==OriginalCount))
  890.                         {
  891.                           if (!ReadILBM(Global,IFFHandle,&Sprites->Sprites[i],Sprites))
  892.                         {
  893.                           Sprites->Sprites[i].Flags|=SPRTF_FREE;
  894.                           UpdateProgressWindow(Global);
  895.                         }
  896.                           else
  897.                         {
  898.                           Error=Global->Error;
  899.                         }
  900.                           break;
  901.                         }
  902.                     }
  903.                     }
  904.                   OriginalCount++;
  905.                 }
  906.                 }
  907.             }
  908.               while (Sprites && !Error);
  909.               if (Sprites && Error!=IFFERR_EOC)
  910.             {
  911.               GS_FreeSprites(Sprites,Global->Screen);
  912.               Sprites=NULL;
  913.             }
  914.             }
  915.         }
  916.           CloseIFF(IFFHandle);
  917.         }
  918.       if (!Sprites)
  919.         {
  920.           Global->Error=Error;
  921.         }
  922.       FreeIFF(IFFHandle);
  923.     }
  924.       else
  925.     {
  926.       Global->Error=ERROR_NO_FREE_STORE;
  927.     }
  928.     }
  929.   else
  930.     {
  931.       Global->Error=IoErr();
  932.     }
  933.   return Sprites;
  934. }
  935.  
  936. /************************************************************************/
  937. /*                                    */
  938. /* Make the reflected sprites                        */
  939. /*                                    */
  940. /************************************************************************/
  941.  
  942. static INLINE struct GS_Sprites *MakeReflectedSprites(struct Global *Global, struct GS_Sprites *Sprites)
  943.  
  944. {
  945.   int Changed;
  946.  
  947.   do
  948.     {
  949.       ULONG i;
  950.       struct GS_Sprite *Sprite;
  951.  
  952.       Changed=FALSE;
  953.       Sprite=Sprites->Sprites;
  954.       i=Sprites->SpriteCount;
  955.       while (i)
  956.     {
  957.       if (!Sprite->Image)
  958.         {
  959.           struct GS_Sprite *Source;
  960.  
  961.           Source=&Sprites->Sprites[Sprite->Width];
  962.           if (Source->Image)
  963.         {
  964.           assert(!(Sprite->Flags & SPRTF_ORIGINAL));
  965.           if (Source->Flags & SPRTF_NOIMAGE)
  966.             {
  967.               Sprite->Flags|=SPRTF_NOIMAGE;
  968.             }
  969.           if (Source->Flags & SPRTF_NOMASK)
  970.             {
  971.               Sprite->Flags|=SPRTF_NOMASK;
  972.             }
  973.           if (Sprite->Flags & (SPRTF_VERTICAL | SPRTF_HORIZONTAL | SPRTF_COPY))
  974.             {
  975.               WORD Width, Height;
  976.               ULONG Depth;
  977.  
  978.               Sprite->Flags|=SPRTF_FREE;
  979.               if ((Sprite->Flags & SPRTF_HORIZONTAL) && (Sprite->Flags & SPRTF_VERTICAL))
  980.             {
  981.               Width=Source->Height;
  982.               Height=Source->Width;
  983.             }
  984.               else
  985.             {
  986.               Width=Source->Width;
  987.               Height=Source->Height;
  988.             }
  989.               Depth=GetBitMapAttr(Source->Image,BMA_DEPTH);
  990.               if ((Sprite->Image=AllocBitMap(Width,Height,Depth,BMF_INTERLEAVED,
  991.                              Global->Screen->RastPort.BitMap)))
  992.             {
  993.               ULONG MaskStandard;
  994.  
  995.               if (Source->Mask)
  996.                 {
  997.                   MaskStandard=GetBitMapAttr(Sprite->Image,BMA_FLAGS) & BMF_STANDARD;
  998.                   if (MaskStandard)
  999.                 {
  1000.                   if ((Sprite->Mask=AllocBitMap(Width,Height,1,0,NULL)))
  1001.                     {
  1002.                       WORD Plane;
  1003.  
  1004.                       for (Plane=1; Plane<Depth; Plane++)
  1005.                     {
  1006.                       Sprite->Mask->Planes[Plane]=Sprite->Mask->Planes[0];
  1007.                     }
  1008.                     }
  1009.                 }
  1010.                   else
  1011.                 {
  1012.                   Sprite->Mask=AllocBitMap(Width,Height,Depth,BMF_INTERLEAVED,
  1013.                                Global->Screen->RastPort.BitMap);
  1014.                 }
  1015.                   if (!Sprite->Mask)
  1016.                 {
  1017.                   Global->Error=ERROR_NO_FREE_STORE;
  1018.                   GS_FreeSprites(Sprites,Global->Screen);
  1019.                   return NULL;
  1020.                 }
  1021.                 }
  1022. #ifdef DEBUG
  1023.               else
  1024.                 {
  1025.                   assert(!Sprite->Mask);
  1026.                 }
  1027. #endif
  1028.               if ((Sprite->Flags & SPRTF_HORIZONTAL) && (Sprite->Flags & SPRTF_VERTICAL))
  1029.                 {
  1030.                   WORD Row;
  1031.  
  1032.                   for (Row=0; Row<Width; Row++)
  1033.                 {
  1034.                   WORD Column;
  1035.  
  1036.                   for (Column=0; Column<Height; Column++)
  1037.                     {
  1038.                       BltBitMap(Source->Image,Column,Row,Sprite->Image,Row,Column,1,1,0xc0,0xff,NULL);
  1039.                       if (Sprite->Mask)
  1040.                     {
  1041.                       BltBitMap(Source->Mask,Column,Row,Sprite->Mask,Row,Column,1,1,0xc0,0xff,NULL);
  1042.                     }
  1043.                     }
  1044.                 }
  1045.                 }
  1046.               else if (Sprite->Flags & SPRTF_VERTICAL)
  1047.                 {
  1048.                   WORD Column;
  1049.  
  1050.                   for (Column=0; Column<Width; Column++)
  1051.                 {
  1052.                   BltBitMap(Source->Image,Column,0,Sprite->Image,Width-Column-1,0,1,Height,0xc0,0xff,NULL);
  1053.                   if (Sprite->Mask)
  1054.                     {
  1055.                       BltBitMap(Source->Mask,Column,0,Sprite->Mask,Width-Column-1,0,1,Height,0xc0,0xff,NULL);
  1056.                     }
  1057.                 }
  1058.                 }
  1059.               else if (Sprite->Flags & SPRTF_HORIZONTAL)
  1060.                 {
  1061.                   WORD Row;
  1062.  
  1063.                   for (Row=0; Row<Height; Row++)
  1064.                 {
  1065.                   BltBitMap(Source->Image,0,Row,Sprite->Image,0,Height-Row-1,Width,1,0xc0,0xff,NULL);
  1066.                   if (Sprite->Mask)
  1067.                     {
  1068.                       BltBitMap(Source->Mask,0,Row,Sprite->Mask,0,Height-Row-1,Width,1,0xc0,0xff,NULL);
  1069.                     }
  1070.                 }
  1071.                 }
  1072.               else if (Sprite->Flags & SPRTF_COPY)
  1073.                 {
  1074.                   BltBitMap(Source->Image,0,0,Sprite->Image,0,0,Width,Height,0xc0,0xff,NULL);
  1075.                   if (Sprite->Mask)
  1076.                 {
  1077.                   BltBitMap(Source->Mask,0,0,Sprite->Mask,0,0,Width,Height,0xc0,0xff,NULL);
  1078.                 }
  1079.                 }
  1080.               if (Sprite->Mask && MaskStandard)
  1081.                 {
  1082.                   Sprite->Mask->Depth=Depth;
  1083.                 }
  1084.               Sprite->Width=Width;
  1085.               Sprite->Height=Height;
  1086.               UpdateProgressWindow(Global);
  1087.               Changed=TRUE;
  1088.             }
  1089.               else
  1090.             {
  1091.               Global->Error=ERROR_NO_FREE_STORE;
  1092.               GS_FreeSprites(Sprites,Global->Screen);
  1093.               return NULL;
  1094.             }
  1095.             }
  1096.           else
  1097.             {
  1098.               Sprite->Width=Source->Width;
  1099.               Sprite->Height=Source->Height;
  1100.               Sprite->Image=Source->Image;
  1101.               Sprite->Mask=Source->Mask;
  1102.               Sprite->Flags=Source->Flags & ~SPRTF_FREE;
  1103.               UpdateProgressWindow(Global);
  1104.               Changed=TRUE;
  1105.             }
  1106.         }
  1107.         }
  1108.       Sprite++;
  1109.       i--;
  1110.     }
  1111.     }
  1112.   while (Changed);
  1113.   return Sprites;
  1114. }
  1115.  
  1116. /****** gamesupport.library/GS_LoadSprites *******************************
  1117. *
  1118. *   NAME
  1119. *    GS_LoadSprites -- load the sprites
  1120. *
  1121. *   SYNOPSIS
  1122. *    Sprites = GS_LoadSprites(Gamename,Screen)
  1123. *       d0                       a0      a1
  1124. *
  1125. *    GS_Sprites *GS_LoadSprites(const char *, struct Screen *);
  1126. *
  1127. *   FUNCTION
  1128. *    Read a sprite file and return a set of bitmaps.
  1129. *
  1130. *   INPUTS
  1131. *    Gamename     - the name of the game. GS_LoadSprites() will append
  1132. *                   ".sprites" to get the filename
  1133. *    Screen       - the screen that we want to open on.
  1134. *
  1135. *   RESULT
  1136. *    Sprites - a pointer to a (read-only) structure containing
  1137. *              the colormap and the image/mask bitmaps.
  1138. *              If NULL, IoErr() will return more information.
  1139. *              If IoErr()>0, then it is a dos error. <0 means IFF error.
  1140. *
  1141. *   NOTE
  1142. *    A normal sprite is returned as a friend-bitmap.
  1143. *    The mask is a friend-bitmap, too!
  1144. *
  1145. *   NOTE
  1146. *    A sprite with no CMAP and depth 1 is not remapped. Instead,
  1147. *    only a BMF_STANDARD image is returned, so you can pass
  1148. *    this to BltTemplate().
  1149. *
  1150. *    Sprites are not shared (because there is no IsFriendBitmap()
  1151. *    function).
  1152. *
  1153. *    Sigh. I wish Commodore (or whoever owns the Amiga these days)
  1154. *    would finally redesign all these broken gfx calls.
  1155. *    graphics.library is not really something that you could
  1156. *    show around without being ashamed. :(
  1157. *
  1158. *************************************************************************/
  1159.  
  1160. SAVEDS_ASM_A0A1(struct GS_Sprites *,LibGS_LoadSprites,char *,Gamename,struct Screen *,Screen)
  1161.  
  1162. {
  1163.   struct GS_Sprites *Sprites;
  1164.   struct Global TheGlobal;
  1165.  
  1166.   Sprites=NULL;
  1167.   TheGlobal.SpritesDone=0;
  1168.   TheGlobal.Screen=Screen;
  1169.   TheGlobal.Error=0;
  1170.   if ((TheGlobal.LibBase=OpenLibrary(IFFParseName,36)))
  1171.     {
  1172.       char *Filename;
  1173.  
  1174.       {
  1175.     char *Name;
  1176.  
  1177.     Name=Gamename;
  1178.     Filename=GS_FormatString("PROGDIR:%s.sprites",&Name,NULL,NULL);
  1179.       }
  1180.       if (Filename!=NULL)
  1181.     {
  1182.       if ((TheGlobal.File=Open(Filename,MODE_OLDFILE)))
  1183.         {
  1184.           struct SetInfo *SetInfo;
  1185.           ULONG SetCount;
  1186.  
  1187.           CreateProgressWindow(&TheGlobal,Gamename);
  1188.           ObtainSemaphore(&Screen->ViewPort.ColorMap->PalExtra->pe_Semaphore);
  1189.           if ((SetInfo=GetSetInfo(&TheGlobal,&SetCount)))
  1190.         {
  1191.           struct SetInfo *TheSet;
  1192.  
  1193.           TheSet=SelectSet(&TheGlobal,SetInfo,SetCount);
  1194.           if ((Sprites=ReadOriginalSprites(&TheGlobal,TheSet)))
  1195.             {
  1196.               Sprites=MakeReflectedSprites(&TheGlobal,Sprites);
  1197.             }
  1198.           GS_MemoryFree(SetInfo);
  1199.         }
  1200.           ReleaseSemaphore(&Screen->ViewPort.ColorMap->PalExtra->pe_Semaphore);
  1201.           CloseProgressWindow(&TheGlobal);
  1202.           Close(TheGlobal.File);
  1203.         }
  1204.       else
  1205.         {
  1206.           TheGlobal.Error=IoErr();
  1207.         }
  1208.       GS_MemoryFree(Filename);
  1209.     }
  1210.       else
  1211.     {
  1212.       TheGlobal.Error=ERROR_NO_FREE_STORE;
  1213.     }
  1214.       CloseLibrary(TheGlobal.LibBase);
  1215.     }
  1216.   SetIoErr(TheGlobal.Error);
  1217.   return Sprites;
  1218. }
  1219.  
  1220. /****** gamesupport.library/GS_FreeSprites *******************************
  1221. *
  1222. *   NAME
  1223. *    GS_FreeSprites -- free sprites loaded with GS_LoadSprites
  1224. *
  1225. *   SYNOPSIS
  1226. *    GS_FreeSprites(Sprites, Screen);
  1227. *                      a0      a1
  1228. *
  1229. *    void GS_FreeSprites(struct GS_Sprites *, struct Screen *);
  1230. *
  1231. *   FUNCTION
  1232. *    Free the sprites. Call this when you're done with them.
  1233. *    The recommended usage is to close the window first, to make
  1234. *    sure that the colors are no longer visible.
  1235. *
  1236. *   INPUTS
  1237. *    Sprites - the sprites returned from GS_LoadSprites(). NULL
  1238. *              is valid.
  1239. *    Screen  - the screen that we used to allocate the sprites
  1240. *
  1241. *   RESULT
  1242. *    More free memory. More free colors (possibly).
  1243. *
  1244. *************************************************************************/
  1245.  
  1246. SAVEDS_ASM_A0A1(void,LibGS_FreeSprites,struct GS_Sprites *,Sprites,struct Screen *,Screen)
  1247.  
  1248. {
  1249.   if (Sprites)
  1250.     {
  1251.       ULONG i;
  1252.       struct GS_Sprite *Sprite;
  1253.  
  1254.       GS_FreeColors(Screen,&Sprites->Colors);
  1255.       Sprite=Sprites->Sprites;
  1256.       i=Sprites->SpriteCount;
  1257.       while (i)
  1258.     {
  1259.       if (Sprite->Flags & SPRTF_FREE)
  1260.         {
  1261.           if (Sprite->Image)
  1262.         {
  1263.           if (Sprite->Mask)
  1264.             {
  1265.               if (GetBitMapAttr(Sprite->Image,BMA_FLAGS) & BMF_STANDARD)
  1266.             {
  1267.               Sprite->Mask->Depth=1;
  1268.             }
  1269.               FreeBitMap(Sprite->Mask);
  1270.             }
  1271.           FreeBitMap(Sprite->Image);
  1272.         }
  1273.         }
  1274.       Sprite++;
  1275.       i--;
  1276.     }
  1277.       GS_MemoryFree(Sprites);
  1278.     }
  1279. }
  1280.